package com.axin.common.websocket;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.server.standard.SpringConfigurator;

import com.axin.common.entity.SocketResult;
import com.axin.common.utils.JsonUtil;

//websocket连接URL地址和可被调用配置
@ServerEndpoint(value = "/socketServer/{sessionKey}", configurator = SpringConfigurator.class)
public class WebSocketServer {
	// 日志记录      
	private Logger logger = LoggerFactory.getLogger(WebSocketServer.class);
	// 静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。
	private static int onlineCount = 0;

	// 记录每个用户下多个终端的连接
	//private static Map<String, Set<Session>> userSocket = new HashMap<>();
	private static Map<String, CopyOnWriteArraySet<WebSocketServer>> userSocket = new HashMap<>();
	// 需要session来对用户发送数据, 获取连接特征userId
	private Session session;
	private String sessionKey;

	@OnOpen
	public void onOpen(@PathParam("sessionKey") String sessionKey, Session session) throws IOException {
		this.session = session;
		this.sessionKey = sessionKey;
		onlineCount++;
		// 根据该用户当前是否已经在别的终端登录进行添加操作
		if (userSocket.containsKey(sessionKey)) {
			logger.debug("当前用户id:{}已有其他终端登录", sessionKey);
			CopyOnWriteArraySet<WebSocketServer> set = userSocket.get(sessionKey);
			set.add(this);
		} else {
			logger.debug("当前用户id:{}第一个终端登录", sessionKey);
			CopyOnWriteArraySet<WebSocketServer> set = new CopyOnWriteArraySet<>();
			set.add(this);
			userSocket.put(sessionKey, set);
		}
		logger.info("用户{}登录的终端个数是为{}", sessionKey, userSocket.get(sessionKey).size());
		logger.info("当前在线用户数为：{},所有终端个数为：{}", userSocket.size(), onlineCount);
	}

	@OnClose
	public void onClose() {
		onlineCount--;
		// 移除当前用户终端登录的websocket信息,如果该用户的所有终端都下线了，则删除该用户的记录
		if (userSocket.get(this.sessionKey).size() == 0) {
			userSocket.remove(this.sessionKey);
		} else {
			userSocket.get(this.sessionKey).remove(this);
		}
		logger.info("用户{}登录的终端个数是为{}", this.sessionKey, userSocket.get(this.sessionKey).size());
		logger.info("当前在线用户数为：{},所有终端个数为：{}", userSocket.size(), onlineCount);
	}

	@OnMessage
	public void onMessage(String message, Session session) {
		logger.info("收到来自用户id为：{}的消息：{}", this.sessionKey, message);
		if (session == null)
			logger.info("session null");
	}

	@OnError
	public void onError(Session session, Throwable error) {
		logger.debug("用户id为：{}的连接发送错误", this.sessionKey);
		error.printStackTrace();
	}

	
	
	public Boolean sendMessageToUser(String sessionKey, SocketResult data){
		if (userSocket.containsKey(sessionKey)) {
			logger.info(" 给用户id为：{}的所有终端发送消息：{}", sessionKey, data.getMessage());
			for (WebSocketServer WS : userSocket.get(sessionKey)) {
				logger.info("sessionId为:{}", session.getId());
				try {
					String string = JsonUtil.writeValue(data);
					WS.session.getBasicRemote().sendText(string);
				} catch (IOException e) {
					logger.info(" 给用户id为：{}发送消息失败", sessionKey);
					e.printStackTrace();
					return false;
				}
			}
			return true;
		}
		logger.info("发送错误：当前连接不包含id为：{}的用户", sessionKey);
		return false;
	}

}